<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Team Support for Logical Model Integration</title>
</head>
<body>
<table width="100%" cellpadding="2" cellspacing="5" border="0">
  <tbody>
    <tr> 
      <td bgcolor="#0080c0" valign="top" align="left"> <b><font
 face="Arial,Helvetica" color="#ffffff"> Eclipse 3.2 - Team Support for Logical 
        Model Integration</font></b></td>
    </tr>
  </tbody>
</table>
<h1>Team Support for Logical Model Integration</h1>
<p>Version 3.2 M4</p>
<p>The <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-vcm-home/docs/online/team3.2/model-integration-proposals.html">Proposed 
  Support for Logical Model Integration</a> document outlines all the areas that 
  are targeted to be addressed in 3.2 related to logical model integration support 
  in Eclipse. The purpose of this document is to outline the proposed solutions 
  relating to Team. Feedback is strongly encouraged and may be provided on the 
  platform-team-dev mailing list or in the <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37723">bug 
  37723</a> for this plan item. The API described in this document is available 
  in builds but is not yet final and may undergo some revision before the end 
  of the Eclipse 3.2 development cycle. </p>
<p>This document is broken into the following sections:</p>
<ul>
  <li><strong><a href="#ResourceMapping">Resource Mappings</a></strong>: API that 
    was introduced as provisional in 3.1</li>
  <li><a href="#ModelProvider"><strong>Model Providers</strong></a>: This API 
    servers 2 purposes. It supports the grouping of resource mappings by model 
    for the purpose of performing batch operations and it supports the back-mapping 
    of file-system resources to resource mappings to ensure that team operations 
    include all relevant model elements in a team operation</li>
  <li><strong><a href="#TeamInput">Team Operation Scope</a></strong>: API for 
    translating a set of selected model elements into the complete set of model 
    elements that should be included in a team operation.</li>
  <li><a href="#AutoMerge"><strong>Model-based Merging</strong></a>: API for delegating 
    a merge operation (e.g. cvs update or merge) to a model so that model semantics 
    can be used to ensure model consistency and improve conflict resolution during 
    merge operations.</li>
  <li><strong><a href="#FileHistory">File History</a></strong>: API for describing 
    the history of a file.</li>
</ul>
<p>It also contains a pointer to a download that contains a simple <a
 href="#Example">Library example</a>.</p>
<h2>Overview of API</h2>
<p>The relationship between the APIs presented in this document can be described 
  in terms of a repository operation being performed on a logical model. Some 
  of the API relates to any repository operation while other parts are specific 
  to a merge operation (e.g. a CVS update). Here is a description of the steps 
  required to perform a CVS update on a logical model as it relates to the API 
  contained in this document.</p>
<ol>
  <li>The user selects a set of model elements and chooses Team&gt;Update from 
    the context menu. </li>
  <ul>
    <li>The <em>ResourceMapping API</em> is what makes it possible for repository 
      tooling to recognize that the selected elements are related to file-system 
      resources in some way.</li>
  </ul>
  <li>The selected elements may be part of a higher level model or may only represent 
    part of the contents of a file. The team operation needs to know the complete 
    set of model elements and resources that need to be operated on. </li>
  <ul>
    <li>The <em>ModelProvider API</em> supports the mapping of file-system resources 
      to model elements</li>
    <li>The <em>Team Operation Scope API</em> provides a set of reusable classes 
      that determine the complete input (which we refer to as the scope) of the 
      team operation.</li>
  </ul>
  <li>Once the complete scope of the operation is determined (i.e. the complete 
    set of resources to be operated on), the operation can be performed. For a 
    merge, the semantics of the model may dictate in what order files need to 
    be merged or may be able to reduce the chances of conflicts by using model 
    semantics to perform the merge. 
    <ol>
      <li>The <em>Model-based Merging API</em> allows the team operation to delegate 
        the merge to the model.</li>
      <li>To do so, the team operation must communicate the synchronization state 
        of all the files involved to the model and give the model access to the 
        remote contents of those files so that the model can perform the merge</li>
    </ol>
  </li>
</ol>
<p>The following sections describe each of these API pieces in more detail.</p>
<h2><a name="ResourceMapping"></a>Resource Mappings</h2>
<h3>The Basic Resource Mapping API</h3>
<p>This solution involves adding API to the Resources plugin that maps logical 
  models elements to workspace (i.e. file system) resources. The API is purposely 
  simple with logical model manipulations omitted. A client can't use this interface 
  to display logical models or gain any interesting additional knowledge about 
  it. It's purpose is simply to map one or more model elements to workspace resources. 
</p>
<p>The API consists of the following classes: </p>
<ul>
  <li><strong>ResourceMapping</strong>: The Class to which logical model elements 
    adapt to indicate that the model corresponds to a set of resources in the 
    workspace. The complete <code>ResourceMapping</code> class can be viewed <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ResourceMapping.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">here</a>. 
    The methods of interest are: 
    <ul>
      <li><code>Object getModelObject()</code>: The model object from which the 
        mapping was derived (or adapted).</li>
      <li><code>ResourceTraversal[] getTraversals(ResourceMappingContext, IProgressMonitor)</code>: 
        The resource traversal that cover the resources that constitute the model 
        object.</li>
    </ul>
  </li>
  <li><strong>ResourceTraversal</strong>: A <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ResourceTraversal.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup"><code>ResourceTraversal</code></a> 
    contains a set of resources and a depth flag that indicates the depth to which 
    the resources in the traversal are associated with the originating model object. 
    Resource traversals are provided to a client by a resource mapping in order 
    to describe the contents of a model in such a way that the client (e.g. a 
    repository provider) can perform its operations in as efficient a means as 
    possible. Methods of interest are: 
    <ul>
      <li><code>getResources()</code></li>
      <li><code>getDepth()</code></li>
    </ul>
  </li>
  <li><strong>ResourceMappingContext</strong>: a context that is provided to the 
    resource mapping by the client when obtaining traversals. This context allows 
    the logical model to determine what the remote state of the model is so that 
    the proper resources can be covered by the resource traversals returned by 
    the resource mapping. The use of the<code> <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ResourceMappingContext.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">ResourceMappingContext</a></code> 
    and<code> <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/RemoteResourceMappingContext.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">RemoteResourceMappingContext</a></code> 
    is a bit more complicated and is described <a
 href="#ResourceMappingContext">later</a>.</li>
</ul>
<p>There are two types of plugins that should be interested in resource mappings. 
  Those who provide a model that consists of, or is persisted in, resources in 
  the workspace and those that want to perform operations on resources. The following 
  two sections describe how to associate a resource mapping with a model object 
  and how to contribute menus to objects that adapt to resource mappings.</p>
<h4>Adapting a Model to a ResourceMapping</h4>
<p>Plugins that adapted their model objects to <code>IResource</code> in order 
  to get resource specific actions shown in the context menu can now adapt to 
  <code>ResourceMapping</code> if a richer description of how the object adapts 
  to resources is beneficial. However, they are not required to do so if there 
  is no benefit. For instance a Java compilation unit (i.e. *.java file shown 
  in a JDT view) that now currently adapts to <code>IFile</code> need not adapt 
  to <code>ResourceMapping</code> since nothing is gained. However, a Java package 
  should adapt to <code>ResourceMapping</code> in order to indicate that the package 
  consists of only the files in the corresponding folder and not the subfolders.</p>
<p>The preferred way to adapt model elements to a resource mapping is to use an 
  adapter factory. The following is the XML markup for contributing an adapter 
  factory in a plugin manifest. </p>
<pre style="background-color: rgb(204, 204, 255);">   &lt;extension<br>         point="org.eclipse.core.runtime.adapters"&gt;<br>      &lt;factory<br>            class="org.eclipse.example.library.logical.AdapterFactory"<br>            adaptableType="org.eclipse.example.library.Book"&gt;<br>         &lt;adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/&gt;<br>      &lt;/factory&gt;<br>      &lt;factory<br>            class="org.eclipse.example.library.logical.AdapterFactory"<br>            adaptableType="org.eclipse.example.library.Library"&gt;<br>         &lt;adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/&gt;<br>      &lt;/factory&gt;<br>      ...<br>   &lt;/extension&gt;</pre>
<p>The adapter factory implementation would look something like this:</p>
<pre style="background-color: rgb(204, 204, 255);">public class AdapterFactory implements IAdapterFactory {<br>   public Object getAdapter(Object adaptableObject, Class adapterType) {<br>      if((adaptableObject instanceof EObject) &amp;&amp; adapterType == ResourceMapping.class) {<br>         return new EObjectResourceMapping((EObject)adaptableObject);<br>      }<br>      return null;<br>   }<br><br>   public Class[] getAdapterList() {<br>      return new Class[] {ResourceMapping.class};<br>   }<br>}</pre>
<p>Model objects must implement the <code>IAdaptable</code> interface. When they 
  do so, they must ensure that the Platform adapter manager is consulted. This 
  can be done by either subclassing <code>PlatformObject</code> or by using the 
  following line of code:</p>
<blockquote> 
  <p><code>Platform.getAdapterManager().getAdapter(Object, Class)</code></p>
</blockquote>
<p>The above is the preferable approach. However, the model object can implement 
  the IAdaptable interface and provide a <code>getAdapter(Class)</code> implementation 
  that creates returns an instance of <code>ResourceMapping</code> explicitly 
  when asked for one. This is a more straightforward approach but the least desirable 
  as the model must have explicit knowledge of the adaptation to resources.</p>
<p>In some cases, the provider of a logical model may not want their model to 
  adapt to <code>IResource</code> in every context or may want the object to adapt 
  differently for object contributions than for other contexts. The workbench 
  UI provides a special intermediate adapter API, <code>IContributorResourceAdapter</code>, 
  for this purpose. When objects are being adapted to <code>IResource</code> in 
  the context of object contributions, the workbench first tries to adapt the 
  resource to <code>IContributorResourceAdapter</code> before trying to adapt 
  to <code>IResource</code> directly. A new sub-interface of this interface, <code>IContributorResourceAdapter2</code>, 
  has been added which provides the same capability for <code>ResourceMapping</code>. 
  The only difference is that the model provider should register a factory for<code> 
  IContributorResourceAdapter</code> since the Workbench does an <em>instanceof</em> 
  check to see if the contributed adapter is also an instance of <code>IContributorResourceAdapter2</code>.</p>
<p>The implementation of the <code>ResourceMapping</code> subclass for a Java 
  package would look something like this.</p>
<pre style="background-color: rgb(204, 204, 255);">public class JavaPackageResourceMapping extends ResourceMapping {<br>   IPackageFragment package;<br>   ...<br>   public getModelObject() {<br>      return package;<br>   }<br>   public ResourceTraversals[] getTraversals(<br>             ResourceMappingContext context, <br>             IProgressMonitor monitor) {<br>      return new ResourceTraversal[] { <br>         new ResourceTraversal(<br>            new IResource[] { package.getCorrespondingResource() },<br>            IResource.DEPTH_ONE, IResource.NONE)<br>      }<br>   }<br>}</pre>
<p>This is a fairly straightforward mapping so the implementation is not complex. 
  The complexity of the resource mapping implementation will, of course, vary 
  from model to model. The <code>EObjectResourceMapping</code> example used above 
  is implemented in the example and has a more complicated implementation.</p>
<h4>Contributing Menus to Resource Mappings</h4>
<p>Plug-ins that contribute extensions to adaptable extension points will have 
  to make two changes to support the new <code>ResourceMapping</code> APIs:</p>
<ol>
  <li>Update their plugin.xml files to change the objectClass of their adaptable 
    contributions to <code>ResourceMapping</code> (for those for which this is 
    appropriate).</li>
  <li>Update their actions to work on <code>ResourceMapping</code> instead of 
    <code>IResource</code> and respect the depth constraints provided in the traversals.</li>
  <li>(Optional) provide a <code>ResourceMappingContext</code> if they manage 
    remote resources (more on this <a href="#ResourceMappingContext">below</a>)</li>
</ol>
<p>First of all, plugins that add object contributions to <code>IResource</code> 
  (CVS, Search, Compare) can now add them to <code>ResourceMapping</code> instead, 
  if the action can apply to multiple resources. Here is an XML snippet that contributes 
  a menu action to objects that adapt to resource mappings:</p>
<pre style="background-color: rgb(204, 204, 255);">   &lt;extension<br>       point="org.eclipse.ui.popupMenus"&gt;<br>    	&lt;objectContribution<br>            adaptable="true"<br>            objectClass="org.eclipse.core.resources.mapping.ResourceMapping"<br>            id="org.eclipse.example.library.ResourceMappingContributions"&gt;<br>         &lt;action<br>               label="Show Resource Mappings"<br>               class="org.eclipse.example.library.contributions.ShowResourceMappingsAction"<br>               menubarPath="additions"<br>               id="org.eclipse.example.library.showMappings"/&gt;         <br>      	&lt;/objectContribution&gt;<br>   &lt;/extension&gt;</pre>
<p>Contributions to <code>ResourceMapping</code> will automatically apply to objects 
  that adapt to <code>IResource</code>. This transitive association is handled 
  by the Workbench.</p>
<p>Filtering of the contributions to resource mappings can be done using action 
  filters or expressions. An expression for filtering by project persistent property 
  has been added to allow repository providers to have their menus appear on projects 
  that are mapped to their repositories.</p>
<pre style="background-color: rgb(204, 204, 255);">   &lt;extension<br>       point="org.eclipse.ui.popupMenus"&gt;<br>      &lt;objectContribution<br>            objectClass="org.eclipse.core.resources.mapping.ResourceMapping"<br>            adaptable="true"<br>            id="org.eclipse.team.ccvs.ui.ResourceMapperContributions"&gt;<br>		 &lt;enablement&gt;<br>           &lt;adapt type="org.eclipse.core.resources.mapping.ResourceMapping"&gt;<br>              &lt;test <br>                 property="org.eclipse.core.resources.projectPersistentProperty" <br>                 args="org.eclipse.team.core.repository,org.eclipse.team.cvs.core.cvsnature" /&gt;<br>           &lt;/adapt&gt;<br>         &lt;/enablement&gt;<br>         &lt;action<br>               label="%UpdateAction.label"<br>               definitionId="org.eclipse.team.cvs.ui.update"<br>               class="org.eclipse.team.internal.ccvs.ui.actions.UpdateAction"<br>               tooltip="%UpdateAction.tooltip"<br>               menubarPath="team.main/group2"<br>               id="org.eclipse.team.cvs.ui.update"&gt;<br>         &lt;/action&gt;<br>         ...<br>      	&lt;/objectContribution&gt;<br>   &lt;/extension&gt;</pre>
<p>Actions that have been contributed to the <code>ResourceMapping</code> class 
  will be given a selection that contains one or more <code>ResourceMappings</code>. 
  It is the actions responsibility to translate the resource mapping into a set 
  of resources to be operated on. This can be done by calling <code>getTraversals</code> 
  to get the traversals of the mapping. Traversals are used to allow the clients 
  of the traversal to optimize their operations based on the depth of the resources 
  being traversed. A client may traverse the resource manually or may use the 
  resource and the depth as input into an operation that the action delegates 
  to do the work. As an example, if the user performs a CVS update on a java package 
  and the java package resource mapping maps to a folder of depth one, CVS would 
  issue an appropriate command ("cvs update -l" for those who are curious) which 
  would perform a shallow update on the folder the package represents.</p>
<h3><a name="ResourceMappingContext"></a>Resource Mapping Context</h3>
<p>One of the advantages of a Resource Mapping API is that it allows plug-ins 
  to implement any operations they desire in terms of resource mappings (e.g. 
  CVS update, CVS commit, CVS tag, dirty decoration, etc.). However, the API that 
  has been introduced so far deals only with the local state of the model. When 
  working with a model that may be shared between developers, you end up in a 
  situation where the remote state of the model (i.e. the state of the model that 
  another user has checked-in to the repository) may differ from the state in 
  the workspace. If you performed a CVS update, you would want the local state 
  of the model to match the remote state even if it meant that additional files 
  needed to be included or some files needed to be removed.</p>
<p>This is not an issue for some logical models. For instance, a java package 
  is a container visited to a depth of one, regardless of the remote state of 
  the model. Given this, a repository provider can easily determine that outgoing 
  deletions should be included when committing or that incoming additions should 
  be included when updating. However, the resources that constitute some logical 
  models may change over time. For instance, the resources that constitute a model 
  element may depend of the contents of a manifest file (or some other similar 
  mechanism). In order for the resource mapping to return the proper traversal, 
  it must access the remote contents of the manifest file (if it differs from 
  the local contents) in order to see if there are additional resources that need 
  to be included. These additional resources may not exist in the workspace but 
  the repository provider would know how to make sure they did when the selected 
  action was performed.</p>
<p>In order to support these more complex models, a <code>RemoteResourceMappingContext</code> 
  can be passed to the <code>ResourceMapping#getTraversals</code> method. When 
  a context is provided, the mapping can use it to ensure that all the necessary 
  resources are included in the traversal. If a context is not provided, the mapping 
  can assume that only the local state is of interest. </p>
<h4>When does a ResourceMapping need to worry about the RemoteResourceMappingContext?</h4>
<p>A <code>ResourceMapping</code> need only worry about a context supplied to 
  the <code>getTraversals</code> method in cases were the resources that make 
  up a model change over time and the relationship between the model and resources 
  cannot be described by a simple traversal that is guaranteed to encompass those 
  resources (and only those resources) that constitute the model. For example, 
  although the resources of a Java package may change over time, the package can 
  be described as a folder of depth of one so a resource mapping for java packages 
  would not ned to make use of the resource mapping context. </p>
<p>As a more complicated example, consider an HTML file that contains several 
  images. Let's make the assumption that any images references from an HTML file 
  are part of the model of that file. When updating the local contents of the 
  HTML file from a repository, the user would expect that any new images would 
  be included. The <code>getTraversals</code> method for a <code>ResourceMapping</code> 
  for the HTML file model would look something like this:</p>
<pre style="background-color: rgb(204, 204, 255);">public class HTMLResourceMapping extends ResourceMapping {<br>	   private HTMLFile htmlFile;<br>	   public ResourceTraversal[] getTraversals(ResourceMappingContext context, <br>              IProgressMonitor monitor)<br>	      IResource[] resources = htmlFile.getResources();<br>	      if (context instanceof RemoteResourceMappingContext) {<br>	         // Look for any additional resources on the server<br>	         RemoteResourceMappingContext remoteContext = (RemoteResourceMappingContext)context;<br>	         IFile file = htmlFile.getFile();<br>	         if (remoteContext.hasRemoteChange(file, monitor)) {<br>	        	 IStorage storage = remoteContext.fetchRemoteContents(file, monitor);<br>	        	 IResource[] additionalResources = getReferences(storage.getContents());<br>	        	 resources = combine(resources, additionalResources);<br>	         }<br>	         if (remoteContext.isThreeWay() &amp;&amp; remoteContext.hasLocalChange(file, monitor)) {<br>        		 IStorage storage = remoteContext.fetchBaseContents(file, monitor);<br> 	             IResource[] additionalResources = getReferences(storage.getContents());<br>	             resources = combine(resources, additionalResources);<br>	         }<br>	      }<br>	      return new ResourceTraversal[] { <br>            new ResourceTraversal(resources, IResource.DEPTH_ZERO, IResource.NONE)};<br>	   }<br>}</pre>
<p>Notice that there are two sets of resources included in the model: those derived 
  from the local contents of the HTML file in the workspace and those obtained 
  from the contents of the remote file and base file. In either of these two sets, 
  there may be resources that do not exist in the workspace. For instance, the 
  local HTML file may contain a relative link to an image that does not exist 
  in the workspace. This resource should be included so that it will be fetched 
  if it exists remotely. As for the remote file, it may contain a new copy that 
  references additional images that should be fetched when the new remote contents 
  are downloaded.</p>
<h4>When does a repository need to provide a RemoteResourceMappingContext?</h4>
<p>Any tool that is providing the ability of sharing workspace resources through 
  a repository and is supporting ResourceMappings should provide an appropriate 
  context for determining the relevant remote state of the model resources. The 
  context provides three basic queries:</p>
<ul>
  <li>What type of comparison is being performed: two-way or three-way 
    <ul>
      <li>for two-way, does the local contents differ from the remote contents</li>
      <li>for three-way, are there local changes and are there remote changes</li>
    </ul>
  </li>
  <li>What are the contents of the remote (and base for three-way) counterparts 
    of the file</li>
  <li>What are the remote members of a folder</li>
</ul>
<p>The answer to the first question above depends on the type of operation that 
  is being performed. Typically, updates and merges are three-way while comparisons 
  and replace operations are two-way.</p>
<p>The Eclipse Team API includes a <code>Subscriber</code> class that defines 
  an API for providing the synchronization state between the local workspace and 
  a remote server. A <code><a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/mapping/ResourceTraversal.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">SubscriberResourceMappingContext</a></code> 
  has been created that uses a <code>Subscriber</code> to access the necessary 
  remote state. Clients that have a <code>Subscriber</code> do not need to do 
  any additional work to get a resource mapping context.</p>
<h2><a name="ModelProvider"></a>Model Providers</h2>
<p>Model providers are a means to group related resource mappings together. Here 
  is a link to the <code><a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ModelProvider.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">ModelProvider</a></code><a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ModelProvider.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup"> 
  class</a>. This class serves two main purposes:</p>
<ol>
  <li>From a model provider, clients can then obtain additional API pieces for 
    performing operations on a set of resource mappings.</li>
  <li>Given a set of file-system resources, clients can query whether a model 
    provider has model elements persisted in those resources and, if it does, 
    obtain the set of resource mappings that describe the relationship.</li>
</ol>
<p>The following is an example of a modelProvider extension definition.</p>
<pre style="background-color: rgb(204, 204, 255);">   &lt;extension<br>         id="modelProvider"<br>         name="Library Example"<br>         point="org.eclipse.core.resources.modelProviders"&gt;<br>      &lt;modelProvider<br>            class="org.eclipse.team.examples.library.adapt.LibraryModelProvider"<br>            name="Library Example"/&gt;<br>      &lt;extends-model id="org.eclipse.core.resources.modelProvider"/&gt;<br>      &lt;enablement&gt;
         &lt;test property=&quot;org.eclipse.core.resources.projectNature&quot; 
               value=&quot;org.eclipse.team.examples.library.view.nature&quot; /&gt;<br>       &lt;/enablement&gt;<br>   &lt;/extension&gt;<br></pre>
<p>The <code>LibraryModelProvider</code> is a subclass of <code>ModelProvider</code>. 
  The enablement rule is used to match resources that the Library model persists 
  its model in. In the above example, the model provider will match any resource 
  in a project that has the library nature. </p>
<p>Once the model provider is defined, the <code>ResourceMapping#getModelProviderId()</code> 
  method should be overridden to return the id of the model provider.</p>
<pre style="background-color: rgb(204, 204, 255);">   public String getModelProviderId() {<br>      return "org.eclipse.team.examples.library.adapt.modelProvider";<br>   }<br></pre>
<p>To get the proper inverse mapping of resources to resource mapping for those 
  resources that match your provider's enablement rule, you should also override 
  one or both of the <code>getMapping</code> methods. The method that you need 
  to override depends on whether your model has elements that contain multiple 
  resources or not. If your model elements map to a single resource, you can override 
  the method that accepts a single<code>IResource</code> argument. Otherwise, 
  you will need to override the method that accepts an array of resources. Here's 
  an example using the single resource case.</p>
<p>The following example method wraps a library model file in an appropriate resource 
  mapping. It also wraps folders that contain files that are of interest to the 
  model provider.<br>
</p>
<pre style="background-color: rgb(204, 204, 255);">public class LibraryModelProvider extends ModelProvider {<br>	   public ResourceMapping[] getMappings(IResource resource, <br>              ResourceMappingContext context, IProgressMonitor monitor) {<br>          if (isModelFile(resource)) {<br>              // Return a resource mapping on the file<br>              return new LibraryResourceMapping(resource);<br>          } if (containsModelFiles(resource)) {<br>              // Create a deep resource mapping on the container<br>              return new LibraryContainerResourceMapping(resource);<br>          }<br>          // The resource is not of interest to this model provider<br>          return null;<br>	   }<br>}</pre>
<p>Clients can then access the model provider to determine whether the model providers 
  cares about the resources that are about to be operated on. The next section 
  describes API that will be provided to team operations that use the model provider 
  API to determine the complete set of resource mappings to be operated on when 
  a team operation is performed on a set of selected resources or model elements.</p>
<h2><a name="TeamInput"></a>Team Operation Scope</h2>
<p>For team operations, the selected mappings need to be translated into the set 
  of mappings to be operated on. This process involves consulting all model providers 
  to ensure that they get included in operations on resources that match their 
  enablement rules. The term we use to describe the complete set of resource mappings 
  to be operated on is the operation <em>scope</em>. The following API has been 
  provided for this:</p>
<ul>
  <li><code><a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/IResourceMappingScope.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IResourceMappingScope</a></code>: 
    Interface that defines the API for accessing the scope of the operation. It 
    provides access to all the resource mappings being operated on and the traversals 
    for those mappings as they were calculated during the scope building process.</li>
  <li><code><a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/ScopeGenerator.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">ScopeGenerator</a></code>: 
    Class that is used to build a scope given a set of input mappings and a resource 
    mapping context.</li>
</ul>
<p>The code for creating an initializing an input would look something like this:</p>
<pre style="background-color: rgb(204, 204, 255);">ResourceMapping[] selectedMappings = getSelectedMappings();<br>ResourceMappingContext context = getResourceMappingContext();<br>ScopeGenerator builder = new ScopeGenerator();<br>IResourceMappingScope scope = builder.prepareScope(selectedMappings, context, monitor);<br>if (scope.hasAdditionalMappings()) {<br>   // inform user of additional mappings<br>}<br>// Now get the set of mappings to be operated on<br>ResourceMapping[] operationMappings = scope.getMappings();<br>// Get the traversals that were cached during the input determination process<br>ResourceTraversal[] allTraversals = scope.getTraversals();</pre>
<p>Team operations will provide the set of selected resource mappings and a resource 
  mapping context. They will then call <code>buildScope</code> which calculates 
  all the resource mappings that need to be included in the operation. The scope 
  also caches the results so they do not need to be recalculated during the operation. 
  You can get all the traversals or only those for a particular mapping.</p>
<h2><a name="AutoMerge"></a>Model-based Merging</h2>
<p>This section offers a brief explanation of what model based merging involves 
  and provides pointers to example implementations in the SDK.</p>
<ul>
  <li>The team provider needs to calculate the synchronization state of all the 
    resources involved in the merge. This is done by subclassing <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.ui/src/org/eclipse/team/ui/operations/ResourceMappingMergeOperation.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">ResourceMappingMergeOperation</a> 
    and overriding the <code>buildContext</code> method to return an <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/IMergeContext.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IMergeContext</a>. 
    The merge context provides the model access to the synchronization state of 
    the files involved (see the <code>getSyncInfoTree()</code> method) along with 
    access to the contents of the files (see <code>SyncInfo#getRemote()</code> 
    and <code>SyncInfo#getBase()</code>). The CVS UI plugin contains an a merge 
    operation subclass named <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/CVSMappingMergeOperation.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">CVSMappingMergeOperation</a>.</li>
  <li>The model needs to adapt it's model provider to an instance of <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/IResourceMappingMerger.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IResourceMappingMerger</a>. 
    The merge operation delegates the merge to the registered merger. The platform 
    has a default implementation, <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/DefaultResourceMappingMerger.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">DefaultResourceMappingMerger</a>, 
    that performs a text-based merge on the files using the IStreamMerger registered 
    for that file type.</li>
</ul>
<h3>Synchronization and Merge Context</h3>
<p>An important aspect of model-based merging is the API used to communicate the 
  synchronization state of the resources involved to the model provider. There 
  are two interfaces of interest:</p>
<ul>
  <li><a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/ISynchronizationContext.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">ISynchronzationContext</a>: 
    provides access to the synchronization stat of all resources within the scope 
    of the operation. The following API pieces are used to describe the synchronization 
    state of resources. 
    <ul>
      <li><a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffTree.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IDiffTree</a>/<a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/IResourceDiffTree.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IResourceDiffTree</a>: 
        data structure that contains the synchronization state for all resources 
        in the operation scope that are out-of-sync.</li>
      <li><a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffNode.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IDiffNode</a>/<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/ITwoWayDiff.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">ITwoWayDiff</a>//<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/IResourceDiff.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IResourceDiff</a>/<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/IThreeWayDiff.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IThreeWayDiff</a>: 
        describes the synchronization of a single resource</li>
      <li><a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariant.java?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">IResourceVariant</a>: 
        provides access to the base or remote file stat and contents that were 
        used to determine the synchronization state for a local resource. </li>
    </ul>
  </li>
  <li><a
 href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/IMergeContext.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IMergeContext</a>: 
    a synchronization context with additional methods that support merging.</li>
</ul>
<h3>Model Content in Team Operation Views</h3>
<p>API has been added in M4 that allows models to provide a team-aware content 
  provider that can be used by Team providers to display the effetcs of team operation 
  in termes of model elements and hierarchies. The CVS Team&gt;Update context 
  menu action in Eclipse 3.2 Milestone 4 (M4) can be configured to display logical 
  model elements and hierarchies when previewing the effects of an update. You 
  must turn on the &quot;Perform client side merges on update&quot; preference 
  on the <strong>Team&gt;CVS&gt;Work In Progress</strong> preference page.</p>
<p><img src="updatePrefs.png" width="419" height="150"></p>
<p>In M4, Java implements a team-aware content provider which allows the effects 
  of an update to be shown with respect to the Java model.</p>
<p><img src="update.png" width="410" height="281"></p>
<p>There are three steps required to create a team-aware content provider</p>
<ol>
  <li>Create a extension to the <em>org.eclipse.ui.navigator.navigatorContent</em> 
    extension point. Minimally, you will need to provide a content provider and 
    label provider and an enablement rule that matches the appropriate model elements. 
    The enablement sule should also match both <code>IResourceMappingScope</code> 
    and <code>ISynchronizationContext</code> as either of these could be used 
    as the input object to a Team viewer.</li>
  <li>Associate your <em>navigatorContent</em> extension with the Team viewer 
    using the <em>org.eclipse.ui.navigator.viewer</em> extension point. The Team 
    viewer id is <em>org.eclipse.team.ui.navigatorViewer</em>.</li>
  <li>Bind your content extension to your model provider using the <em>org.eclipse.team.ui.teamContentProviders</em> 
    extenson point.</li>
</ol>
<p>The following xml shows how the Java content provider is made team-aware.</p>
<pre style="background-color: rgb(204, 204, 255);">  &lt;extension point=&quot;org.eclipse.ui.navigator.navigatorContent&quot;&gt;<br>      &lt;navigatorContent<br>            contentProvider=&quot;org.eclipse.jdt.internal.ui.model.JavaSynchronizationContentProvider&quot;<br>            id=&quot;org.eclipse.jdt.ui.resourceContent&quot;<br>            labelProvider=&quot;org.eclipse.jdt.internal.ui.model.JavaSynchronizationLabelProvider&quot;<br>            name=&quot;%JavaModelContent.name&quot;&gt;<br>         &lt;enablement&gt;<br>            &lt;or&gt;<br>               &lt;instanceof value=&quot;org.eclipse.jdt.internal.ui.model.JavaModelProvider&quot;/&gt;<br>               &lt;instanceof value=&quot;org.eclipse.jdt.core.IJavaElement&quot;/&gt;<br>               &lt;instanceof value=&quot;org.eclipse.team.core.mapping.IResourceMappingScope&quot;/&gt;<br>               &lt;instanceof value=&quot;org.eclipse.team.core.mapping.ISynchronizationContext&quot;/&gt;<br>            &lt;/or&gt;<br>         &lt;/enablement&gt;<br>      &lt;/navigatorContent&gt;<br>   &lt;/extension&gt;

   &lt;extension point=&quot;org.eclipse.ui.navigator.viewer&quot;&gt;<br>      &lt;viewerContentBinding viewerId=&quot;org.eclipse.team.ui.navigatorViewer&quot;&gt;<br>         &lt;includes&gt;<br>            &lt;contentExtension isRoot=&quot;true&quot;<br>                  pattern=&quot;org.eclipse.jdt.ui.resourceContent&quot;/&gt;<br>         &lt;/includes&gt;<br>      &lt;/viewerContentBinding&gt;
   &lt;/extension&gt;

   &lt;extension&gt;
         id=&quot;jdtContentProvider&quot;<br>         point=&quot;org.eclipse.team.ui.teamContentProviders&quot;&gt;<br>      &lt;teamContentProvider<br>            contentExtensionId=&quot;org.eclipse.jdt.ui.resourceContent&quot;<br>            modelProviderId=&quot;org.eclipse.jdt.ui.modelProvider&quot;/&gt;<br>   &lt;/extension&gt;
</pre>
<p>The <code><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/model/JavaSynchronizationContentProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">JavaSynchronizationContentProvider</a></code> 
  and <code><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/model/JavaSynchronizationLabelProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">JavaSynchronizationLabelProvider</a></code> 
  classes in the above example are subclasses of <code><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationContentProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">SynchronizationContentProvider</a></code> 
  and <code><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationLabelProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">SynchronizationLabelProvider</a></code> 
  and make use of the synchronization context to provide filtering and label decoration.</p>
<h2><a name="FileHistory"></a>File History</h2>
<p>The proposed file history API consists of the following interfaces:</p>
<ul>
  <li><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/filehistory/IFileHistoryProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IFileHistoryProvider</a>: 
    Obtained from a RepositoryProvider, the file history provider allows clients 
    to obtain the file history of a particular file.</li>
  <li><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/filehistory/IFileHistory.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IFileHistory</a>: 
    A data structure that allows access to the history of a file</li>
  <li><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/filehistory/IFileRevision.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IFileRevision</a>: 
    The description of a single revision or state of a file at a particular poin 
    tin time in its history.</li>
</ul>
<p>Along with this API, a generic file history view is being proposed. A preview 
  version is available in M4.</p>
<p><img src="history.png" width="456" height="216"></p>
<h2><a name="Example"></a>EMF Library Example</h2>
<p>This example, available <a
 href="libraryExample.html">here</a>, is built on a model that consists of libraries, 
  books and writers.</p>
<h2>What's Next</h2>
<p>See the <a href="plan.html">Eclipse Team/CVS 3.2 plan</a> for what is happening 
  in M5 and beyond.</p>
<h2>Conclusion</h2>
<p>This document contains a description of the API available so far in 3.2. This 
  is only a portion of the feature set described in the <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-vcm-home/docs/online/team3.2/model-integration-proposals.html">Proposed 
  Support for Logical Model Integration</a> document. Additional API for Team 
  support of logical model integration will be added to the document as it becomes 
  available. Also, the API described in this document may still undergo change 
  in the 3.2 release cycle. The document will be updated with any changes as well.</p>
<h2>Change History</h2>
<p>Changes in version 3.2 M4</p>
<ul>
  <li>Updated to contain a brief description of the new API added in M4. This 
    includes
    <ul>
      <li>IDiffTree/IDiffNode API for describing changes</li>
      <li>Use of Common Navigator framework to support the display of model elements 
        in views and dialogs associated with a Team operation</li>
      <li>File history API</li>
    </ul>
  </li>
</ul>
<p>Changes in version 3.2 M3</p>
<ul>
  <li>Updated 3.1 <a
 href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-vcm-home/docs/online/team3.1/logical-physical-mappings.html">Resource 
    Mapping</a> document to reflect new support available in 3.2 M3.<br>
  </li>
</ul>
</body>
</html>
